﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Expression.Interactivity;
using System.Windows.Interactivity;
using Microsoft.Devices.Sensors;
using Microsoft.Xna.Framework;
using System.Windows.Threading;
using System.Threading;
using System.IO.IsolatedStorage;

namespace girapong
{

    public partial class rally : PhoneApplicationPage
    {
        public const int WIDTH = 768;
        public const int HALFWIDTH = 384;
        public const int HEIGHT = 480;
        public const int HALFHEIGHT = 240;

        protected Accelerometer accelerometer;
        public int numBalls { get; set; }
        public int numLifes { get; set; }
        public int nextLife { get; set; }
        public List<ball> ballList { get; set; }
        public List<item> itemList { get; set; }
        public List<SolidBlock> blockList { get; set; }
        public List<SolidBlock> inactiveBlockList { get; set; }
        public int score { get; set; }
        public bar _barPlayer { get; set; }
        private DispatcherTimer dtThrowingBalls;

        private DispatcherTimer dtCleaningBalls;
        private warning warnings;
        public int refreshTimeAccelerometer { get; set; } //miliseconds
        public rally()
        { 
            InitializeComponent();
            startAccelerometer();
            btnGuardarPuntuacion.Visibility = Visibility.Collapsed;
            btnVolver.Visibility = Visibility.Collapsed;
            nextLife = 5;
            numLifes = 10;
            _barPlayer = new bar(System.Windows.Media.Color.FromArgb(255, 0, 0, 255), 0, 0);
            this.LayoutRoot.Children.Add(_barPlayer.rectangle);
            _barPlayer.move(_barPlayer.rectangle.Margin.Left, HEIGHT - _barPlayer.rectangle.Height);
            ballList = new List<ball>();
            itemList = new List<item>();
            dtThrowingBalls = new DispatcherTimer();
            dtThrowingBalls.Interval = TimeSpan.FromMilliseconds(1000);
            dtThrowingBalls.Tick += new EventHandler(throwBall);
            dtThrowingBalls.Start();
            dtCleaningBalls = new DispatcherTimer();
            dtCleaningBalls.Interval = TimeSpan.FromMilliseconds(20000);
            dtCleaningBalls.Tick += new EventHandler(throwBroomy);
            dtCleaningBalls.Start();
            accelerometer.Start();
            txtSiguienteVida.Text = nextLife.ToString();
            txtVidas.Text = numLifes.ToString();

            blockList = new List<SolidBlock>();
            // Blocks list
            Random x = new Random();
            int n = x.Next(1, 3);
            for (int i = 0; i < n; i++)
            {
                int w = x.Next(40, 200);
                int h = x.Next(40, 200);
                int x_ = x.Next(0, screen.WIDTH - 2*w);
                int y = x.Next(0, screen.HEIGHT - 2*h);

                SolidBlock blocky = new SolidBlock(this, x_, y, w, h);
                blockList.Add(blocky);
            }
            warnings = new warning(null, this);
        }
        public bool startAccelerometer()
        {
            bool ok = false;
            if (!Accelerometer.IsSupported)
            {
                MessageBox.Show("El dispositivo no dispone de acelerómetro");
            }
            else
            {
                try
                {
                    ok = true;
                    accelerometer = new Accelerometer();
                    this.refreshTimeAccelerometer = 150;
                    accelerometer.TimeBetweenUpdates = TimeSpan.FromMilliseconds(refreshTimeAccelerometer);
                    accelerometer.CurrentValueChanged +=
                        new EventHandler<SensorReadingEventArgs<AccelerometerReading>>(accelerationDetected);
                }
                catch (Exception)
                {
                    ok = false;
                }
            }
            return ok;
        }
        public void accelerationDetected(object sender, SensorReadingEventArgs<AccelerometerReading> e)
        {
            Dispatcher.BeginInvoke(() => sendReadings(e.SensorReading));
        }
        public void sendReadings(AccelerometerReading lectura)
        {
            Vector3 vector = lectura.Acceleration;
            _barPlayer.move(getPlayerPosition(vector), _barPlayer.rectangle.Margin.Top);
        }
        public double getPlayerPosition(Vector3 v)
        {
            if ((v.Y > 0) && general.isInterval(v.X, -1, -0.866)) return HALFWIDTH - (Math.Abs(v.Y)) * WIDTH;
            else if ((v.Y < 0) && general.isInterval(v.X, -1, -0.866))  return HALFWIDTH + (Math.Abs(v.Y)) * WIDTH;
            else
            {
                if (v.Y > 0) return HALFWIDTH - (Math.Abs(v.Y)) * WIDTH;
            }
            return HALFWIDTH + (Math.Abs(v.Y)) * WIDTH;
        }
        public void throwBroomy(object sender, EventArgs e)
        {
            int p;
            if (score <= 750) p = 17000 - score * 10;
            else p = 9500;
            dtCleaningBalls.Interval = TimeSpan.FromMilliseconds(p);
            Random n = new Random();
            int posX = n.Next((Int32)screen.WIDTH);
            item o = new item("escobita.png", posX, 5, null, this);
            itemList.Add(o);

        }
        public void throwBall(object sender, EventArgs e)
        {
            if (ballList.Count <= 20)
            {
                dtThrowingBalls.Interval = TimeSpan.FromMilliseconds(1000 - score / 10);
                Random n = new Random();
                int posX = n.Next((Int32)screen.WIDTH);
                ball p = new ball(this, System.Windows.Media.Color.FromArgb(255, 0, 255, 0), posX, 0, 1);
                p.setRally(general.generateRandomOnBottomArrowVectorByModule(2 + (score / 20)));
                p.playMovement();
                numBalls++;
                ballList.Add(p);
            }
        }
        public void explodeAll()
        {
            foreach (ball b in ballList)
            {
                b.explode();
            }
            numBalls = 0;
        }
        public void gameover()
        {
            foreach (SolidBlock b in blockList)
            {
                b.dtSpeed.Stop();
                b.timeToAffectSpeed.Stop();
                LayoutRoot.Children.Remove(b.shape);
            }
            foreach (ball b in ballList)b.stopMovement();
            foreach (item i in itemList)i.dtSpeed.Stop();

            dtThrowingBalls.Stop();
            dtCleaningBalls.Stop();
            accelerometer.Stop();

            warn("GAME OVER");
        }
        public void warn(string message)
        {
            warnings.setMessage(message);
            warnings.open();
        }
        public void warn(string type, string message)
        {
            warn("Nuevo nivel: " + message);
        }

        private void btnNuevoPeloteo_Click(object sender, RoutedEventArgs e)
        {
            btnGuardarPuntuacion.IsEnabled = false;
            ScoresList.newScore(score.ToString(), DateTime.Now.ToString("dd/MM/yyyy:HH:mm"), "Resistencia");
        }

        private void btnVolver_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.GoBack();
        }

    }
}